﻿namespace TestApp.DataService
{
    using System;
    using System.Diagnostics.Contracts;
    using System.Reactive.Concurrency;
    using System.Reactive.Linq;
    using Contracts;
    using JetBrains.Annotations;

    internal sealed class DataProvider : IDataProvider
    {
        private const double IntervalMs = 100;
        private readonly IDataRandomizer _dataRandomizer;
        private readonly IObservable<DataEntityDto> _dataSource;

        public DataProvider(
            [NotNull] IScheduler scheduler,
            [NotNull] IDataRandomizer dataRandomizer)
        {
            Contract.Requires<ArgumentNullException>(scheduler != null);
            Contract.Requires<ArgumentNullException>(dataRandomizer != null);
            _dataRandomizer = dataRandomizer;

            _dataSource = (
                from tick in Observable.Interval(TimeSpan.FromMilliseconds(IntervalMs), scheduler)
                select GenerateEntity()).Publish().RefCount();
        }

        public IObservable<DataEntityDto> CreateDataSource()
        {
            Contract.Ensures(Contract.Result<IObservable<DataEntityDto>>() != null);
            return _dataSource;
        }

        [NotNull] private DataEntityDto GenerateEntity()
        {
            Contract.Ensures(Contract.Result<DataEntityDto>() != null);
            var newEntity = new DataEntityDto(_dataRandomizer.GenerateIndex());
            for (var paramIndex = 0; paramIndex < EntityDto.ParameterCount; paramIndex++)
            {
                newEntity.Parameters[paramIndex] = _dataRandomizer.GenerateParameterValue();
            }

            return newEntity;
        }
    }
}